package structures;

public class Cell {
	
	Position pos;
	int state;
	int extra;

	// possible attributes
	// home to be computed to save vars
	static final int BELONGS_TO_TEAM_2 	= 0x01;
	static final int IS_FREE 			= 0x02;
	static final int IS_WALL 			= 0x04;
	static final int IS_A_HOME 			= 0x08;	
	static final int IS_A_JAIL 			= 0x10;	
	static final int HAS_BOMBS 			= 0x20;
	static final int HAS_A_FLAG 		= 0x40;
	// need to go to player to find which one
	static final int HAS_A_PLAYER 		= 0x80;
	
	/* Constructor */
	public Cell( int index, char character, int numCols ) {
		// cell array index to position (start at 1,1)
		this.pos = new Position( (index/numCols)+1, (index%numCols)+1 );
		// set team
		if ( pos.col >= numCols/2 ) this.state |= BELONGS_TO_TEAM_2;
		
		switch( character ) {
			case ' ':
				this.state |= IS_FREE; break;
			case '#':
				this.state |= IS_WALL; break;
			case 'h':
				this.state |= IS_A_HOME; 
				Maze.home1Positions.add(pos);			
				break;
			case 'H':
				this.state |= IS_A_HOME; 
				Maze.home2Positions.add(pos);
				break;
			case 'j':
				this.state |= IS_A_JAIL; 
				Maze.jail1Positions.add(pos);
				//System.out.println( Integer.toBinaryString(state));
				break;
			case 'J':
				this.state |= IS_A_JAIL; 
				Maze.jail2Positions.add(pos);
				//System.out.println( character + pos.toString() + isJail2() + isHome1()  );
				break;
			default:
				break;
		}
	}
	
	// access position
	public Position getPosition() { return pos; }
	
	// get states
	public boolean belongsToTeam1() {
		return !belongsToTeam2();
	}
	public boolean belongsToTeam2() {
		return (state & BELONGS_TO_TEAM_2) != 0;
	}
	public boolean isFree() {
		return (state & IS_FREE) != 0;
	}
	public boolean isWall() {
		return (state & IS_WALL) != 0;
	}
	public boolean isJail() {
		return (state & IS_A_JAIL) != 0;
	}
	public boolean isHome() {
		return (state & IS_A_HOME) != 0;
	}
	public boolean isHome1() {
		return isHome() && belongsToTeam1();
	}
	public boolean isHome2() {
		return isHome() && belongsToTeam2();
	}
	public boolean isJail1() {
		return isJail() && belongsToTeam1();
	}
	public boolean isJail2() {
		return isJail() && belongsToTeam2();
	}
	public boolean hasAFlag() {
		return (state & HAS_A_FLAG) != 0;
	}
	public boolean hasBombs() {
		return (state & HAS_BOMBS) != 0;
	}
	public boolean hasAPlayer() {
		return (state & HAS_A_PLAYER) != 0;
	}
	
	/* change state */
	
	// should be a wall, make free
	// XOR 1 1 = 0, 0 1 = 1, always applying T 
	public void blast() throws Exception {
		if ( isWall() )
			state = state ^ (IS_WALL | IS_FREE);
		else {
			throw new Exception("Cell should be a wall to be blasted.");
		}
	}
	
	// if has attribute, will remove.  Else, will enable.
	public void toggleHasBombs() {
		state = state ^ HAS_BOMBS;
	}
	public void toggleHasAPlayer() {
		state = state ^ HAS_A_PLAYER;
	}
	public void toggleHasAFlag() {
		state = state ^ HAS_A_FLAG;
	}

	
}
